#include "choosefrienddialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include <QScrollBar>
#include <QPainter>
#include "toast.h"

#include "model/datacenter.h"
#include "debug.h"

using namespace model;

////////////////////////
/// 选择好友窗口
///////////////////////
ChooseFriendDialog::ChooseFriendDialog(QWidget *parent, const QString& userId)
    :QDialog(parent)
    ,userId(userId)
{
    // 1 设置窗口基本属性
    this->setWindowTitle("选择好友");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setFixedSize(750, 550);
    this->setStyleSheet("QDialog { background-color: rgb(255, 255, 255);}");
    this->setAttribute(Qt::WA_DeleteOnClose);

    // 2 创建布局管理器
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    this->setLayout(layout);

    // 3 针对左侧窗口进行初始化
    initLeft(layout);

    // 4 针对右侧窗口进行初始化
    initRight(layout);

    // 5. 加载数据到窗口中
    initData();


}


////////////////////////
/// 选择好友窗口中一个元素
///////////////////////
ChooseFriendItem::ChooseFriendItem(ChooseFriendDialog* owner, const QString& userId, const QIcon &avatar, const QString &name, bool checked)
    :userId(userId)
{
    // 1 设置控件基本属性
    this->setFixedHeight(50);
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 2 设置布局管理器
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setSpacing(10);
    layout->setContentsMargins(20, 0, 20, 0);
    this->setLayout(layout);

    // 3 创建复选框
    checkBox = new QCheckBox();
    checkBox->setChecked(checked);
    checkBox->setFixedSize(25, 25);
    QString style = "QCheckBox::indicator { width: 20px; height: 20px; image: url(:/resource/image/unchecked.png);}";
    style += "QCheckBox::indicator::checked {image: url(:/resource/image/checked.png);}";
    //应用父元素背景效果
    style += "QCheckBox {background-color: transparent;}";
    checkBox->setStyleSheet(style);

    // 4 创建头像
    avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIconSize(QSize(40, 40));
    avatarBtn->setIcon(avatar);

    // 5 创建名字
    nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel { background-color: transparent;}");

    // 6 添加上述内容到布局管理器中
    layout->addWidget(checkBox);
    layout->addWidget(avatarBtn);
    layout->addWidget(nameLabel);

    // 7 连接信号槽
    connect(checkBox, &QCheckBox::toggled, this, [ = ](bool checked){
        if (checked)
        {
            //勾选了复选框,把Item添加到右侧的已选择区
            owner->addSelectedFriend(userId, avatar, name);
        }
        else
        {
            //取消了复选框, 保存userId根据userI遍历删除
            owner->deleteSelectedFriend(userId);

        }
    });

}

void ChooseFriendItem::paintEvent(QPaintEvent *event)
{
    (void) event;
    //根据鼠标进入状态决定绘制成不同颜色
    QPainter painter(this);
    if (isHover)
    {
        //绘制成深色
        painter.fillRect(this->rect(), QColor(230, 230, 230));

    }
    else
    {
        //绘制成浅色
        painter.fillRect(this->rect(), QColor(255, 255, 255));
    }
}

void ChooseFriendItem::enterEvent(QEnterEvent *event)
{
    (void) event;
    isHover = true;
    //更新界面
    this->update();
    //或者使用
    //this->repaint();
}

void ChooseFriendItem::leaveEvent(QEvent *event)
{
    (void)event;
    isHover = false;
    this->update();
}

void ChooseFriendDialog::initLeft(QHBoxLayout *layout)
{
    // 1 创建滚动区域
    QScrollArea* scrollArea = new QScrollArea();
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    scrollArea->setWidgetResizable(true);
    scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBal::horizontal {height: 0px;}");
    scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar::vertical {width: 2px; background-color: rgb(255, 255, 255);}");
    scrollArea->setStyleSheet("QScrollArea { border: noe;}");
    layout->addWidget(scrollArea, 1);

    // 2. 创建QWidget设置进滚动区域
    totalContainer =new QWidget();
    totalContainer->setObjectName("totalContainer");

    totalContainer->setStyleSheet("#totalContainer {background-color: rgb(255, 255, 255);}");
    scrollArea->setWidget(totalContainer);

    // 3 创建左侧子窗口垂直布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setSpacing(0);
    vlayout->setAlignment(Qt::AlignTop);
    totalContainer->setLayout(vlayout);

    // 4 还需要进一步添加vlayout内部元素才能看到效果
    // 此处先构造测试数据,后续接入服务器,从服务器拿到真实的好友列表,再添加真实数据
#if TEST_UI
    QIcon defaultAvatar(":/resource/image/defaultAvatar.png");
    for (int i = 0; i < 20; ++i)
    {
        this->addFriend(QString::number(i + 1000),defaultAvatar, "誓约" + QString::number(i), false);
    }
#endif




}

void ChooseFriendDialog::initRight(QHBoxLayout *layout)
{
    // 1 创建右侧布局管理器
    QGridLayout* gridLayout = new QGridLayout();
    gridLayout->setContentsMargins(20, 0, 20, 20);
    gridLayout->setSpacing(10);
    //拉伸系数更改占比
    layout->addLayout(gridLayout, 1);

    // 2 创建 "提示" Label
    QLabel* tipLabel = new QLabel();
    tipLabel->setText("选择联系人");
    tipLabel->setFixedHeight(30);
    tipLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    tipLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    tipLabel->setStyleSheet("QLabel { font-size: 16px; font-weight:700;}");

    // 3 创建滚动区域
    QScrollArea* scrollArea = new QScrollArea();
    scrollArea->setWidgetResizable(true);
    scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(255, 255, 244);}");
    scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 0px;}");
    scrollArea->setStyleSheet("QScrollArea { border: none;}");
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 4 创建滚动区域的 QWidget
    selectedContainer = new QWidget();
    selectedContainer->setObjectName("selectedContainer");
    selectedContainer->setStyleSheet("#selectedContainer { background-color: rgb(255, 255, 255);}");
    scrollArea->setWidget(selectedContainer);

    // 5 创建 "selectedContainer" 中的垂直布局
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setAlignment(Qt::AlignTop);
    selectedContainer->setLayout(vlayout);

    // 6 创建底部按钮
    QString style = "QPushButton { color: rgb(7, 191, 96); background-color:rgb(240, 240, 240); border: none; border-radius: 5px;}";
    style += "QPushButton:hover { background-color: rgb(220, 220, 220);} QPushButton:pressed { background-color: rgb(200, 200, 200);}";
    QPushButton* okBtn = new QPushButton();
    okBtn->setFixedHeight(40);
    okBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    okBtn->setText("完成");
    okBtn->setStyleSheet(style);

    QPushButton* cancelBtn = new QPushButton();
    cancelBtn->setFixedHeight(40);
    cancelBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    cancelBtn->setText("取消");
    cancelBtn->setStyleSheet(style);

    // 7 把上述控件添加到布局 中
    gridLayout->addWidget(tipLabel, 0, 0, 1, 9);
    gridLayout->addWidget(scrollArea, 1, 0, 1, 9);
    gridLayout->addWidget(okBtn, 2, 1, 1, 3);
    gridLayout->addWidget(cancelBtn, 2, 5, 1, 3);

    //构造一些数据用来测试界面
    //if 0 通过勾选左侧按钮生成
#if 0
    QIcon defaultAvatar(":/resource/image/defaultAvatar.png");
    for (int i = 0; i < 20; ++i)
    {
        this->addSelectedFriend(QString::bumber(i + 1000), defaultAvatar, "誓约" + QString::number(i));
    }
#endif


    // 8.添加信号槽处理ok 和cancel的处理
    connect(okBtn, &QPushButton::clicked, this, &ChooseFriendDialog::clickOkBtn);
    connect(cancelBtn, &QPushButton::clicked, this, [=](){
        this->close();
    });
}

void ChooseFriendDialog::clickOkBtn()
{
    // 1. 根据选中的好友列表中得到的元素,得到所有的要创建群聊会话的用户id列表
    QList<QString> userIdList = generateMemberList();
    if (userIdList.size() < 3) {
        Toast::showMessage("群聊成员不足三个无法创建");
        return;
    }
    // 2. 发送网络请求
    DataCenter* dataCenter = DataCenter::getInstance();
    dataCenter->createGroupChatSessionAsync(userIdList);

    //3.关闭当前窗口
    this->close();

}

QList<QString> ChooseFriendDialog::generateMemberList()
{
    QList<QString> result;

    // 1. 把自己添加到结果中
    DataCenter* dataCenter = DataCenter::getInstance();
    if (dataCenter->getMyself() == nullptr) {
        LOG() << "个人信息尚未加载!";
        return result;
    }
    result.push_back(dataCenter->getMyself()->userId);

    // 2.遍历选中列表
    QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(selectedContainer->layout());
    for (int i = 0; i < layout->count(); ++i) {
        auto* item = layout->itemAt(i);
        if (item == nullptr || item->widget() == nullptr) {
            continue;
        }
        auto* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
        result.push_back(chooseFriendItem->getUserId());
    }
    return result;

}

void ChooseFriendDialog::initData()
{
    // 遍历好友列表,把好友列表中的所有元素,添加到这个窗口界面上
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<UserInfo>* friendList = dataCenter->getFriendList();
    if (friendList == nullptr) {
        LOG() << "加载数据时发现好友列表为空";
        return;
    }

    for (auto it = friendList->begin(); it!= friendList->end(); ++it) {
        if (it->userId == this->userId) {
            this->addSelectedFriend(it->userId, it->avatar, it->nickname);
            this->addFriend(it->userId, it->avatar, it->nickname, true);
        } else {
        this->addFriend(it->userId, it->avatar, it->nickname, false);
        }
    }

}

void ChooseFriendDialog::addFriend(const QString&userId, const QIcon &avatar, const QString &name, bool checked)
{
    ChooseFriendItem* chooseFriendItem = new ChooseFriendItem(this, userId, avatar, name, checked);
    totalContainer->layout()->addWidget(chooseFriendItem);

}

void ChooseFriendDialog::addSelectedFriend(const QString&userId, const QIcon &avatar, const QString &name)
{
    ChooseFriendItem* item = new ChooseFriendItem(this, userId, avatar, name, true);
    selectedContainer->layout()->addWidget(item);

}

void ChooseFriendDialog::deleteSelectedFriend(const QString &userId)
{
    //遍历 selectedContainer 中的每个Item, 对比每个 Item 里的userId, 是否是要删除的userId;
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(selectedContainer->layout());
    //由于是遍历加删除,需要从后往前进行
    for (int i = vlayout->count() - 1; i >= 0; --i )
    {
        auto* item = vlayout->itemAt(i);
        if (item == nullptr || item->widget() == nullptr)
        {
            continue;
        }
        ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*> (item->widget());
        if(chooseFriendItem->getUserId() != userId)
        {
            continue;
        }
        else
        {
            vlayout->removeWidget(chooseFriendItem);
            //释放内存直接使用delete可能会导致程序崩溃,deleted该对象时,该对象内部的CheckBox还在使用。
            //改用deleteLater,就把delete操作委托给了QT自身完成
            //QT会在自生用完后去删除
            //delete chooseFriendItem;
            chooseFriendItem->deleteLater();
        }
    }

    //在遍历下左侧列表, 把左侧列表中对应 item的checkBox勾选状态取消掉
    QVBoxLayout* vlayoutLeft = dynamic_cast<QVBoxLayout*> (totalContainer->layout());
    for (int i = 0; i < vlayoutLeft->count(); ++i)
    {
        //vlayoutLeft->itemAt(i);返回值为QLayoutItem*
        auto* item = vlayoutLeft->itemAt(i);
        //当你从 QLayout（如 QVBoxLayout）中获取一个 QLayoutItem* 类型的指针时，你需要检查这个指针是否实际上指向一个 QWidgetItem 对象。
        //如果是，你可以进行类型转换并调用 widget() 函数来获取 QWidget 指针
        //QWidgetItem* Item = dynamic_cast<QWidgetItem*>(item);QLayoutItem中有widget()方法
        if (item == nullptr || item->widget() == nullptr)
        {
            continue;
        }
        else
        {
            ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*> (item->widget());
            if (chooseFriendItem->getUserId() != userId)
            {
                continue;
            }
            // 取消checkBox勾选
            chooseFriendItem->getCheckBox()->setChecked(false);
        }
    }
}






